package com.smile.frame.config.rabbit.component;

import com.smile.frame.config.rabbit.util.RabbitUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;

/**
 * @author LGC
 */
@Slf4j
@Configuration
public class RabbitAutoConfig implements RabbitListenerConfigurer {

    @Bean
    public RabbitUtil rabbitUtil(RabbitTemplate rabbitTemplate) {
        return new RabbitUtil(rabbitTemplate);
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        /**
         * 生产者消息序列化
         */
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        /**
         * mandatory标志告诉broker代理服务器至少将消息route到一个队列中，否则就将消息ReturnsCallback
         * 默认false： 直接丢弃
         * true时：路由不到队列，消息ReturnsCallback
         *
         */
        rabbitTemplate.setMandatory(true);
        /**
         * 消息是否得到交换交换机确认
         */
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            log.info("ConfirmCallback:相关数据：{}", correlationData);
            log.info("ConfirmCallback:确认情况：{}", ack);
            log.info("ConfirmCallback:原因：{}", cause);
        });
        /**
         * 消息无法路由到指定队列触发
         */
        rabbitTemplate.setReturnsCallback(returnedMessage -> {
            log.info("ReturnsCallback 消息：{}", returnedMessage.getMessage());
            log.info("ReturnsCallback 回应码：{}", returnedMessage.getReplyCode());
            log.info("ReturnsCallback 回应信息：{}", returnedMessage.getReplyText());
            log.info("ReturnsCallback 交换机：{}", returnedMessage.getExchange());
            log.info("ReturnsCallback 路由键：{}", returnedMessage.getRoutingKey());
        });
        return rabbitTemplate;
    }


    /*消费者序列化*/
    @Override
    public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) {
        rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
    }

    @Bean
    public MessageHandlerMethodFactory messageHandlerMethodFactory() {
        DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();
        messageHandlerMethodFactory.setMessageConverter(new MappingJackson2MessageConverter());
        return messageHandlerMethodFactory;
    }

}
